﻿using System.ComponentModel;
using System.IO;
using Vlc.DotNet.Core.Interop;
using Vlc.DotNet.Core.Utils;
using System;
using System.Collections.Generic;

namespace Vlc.DotNet.Core
{
  public partial class VlcManager : INotifyPropertyChanged
  {
    private bool myMute;
    private float myPosition;
    private int myVolume = 100;

    /// <summary>
    /// Get/Set autostart
    /// </summary>
    [DefaultValue(false)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public bool AutoStart { get; set; }

    /// <summary>
    /// Get/Set the libvlc, libvlccore files path
    /// </summary>
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public string VlcLibPath
    {
      get { return myVlcLibPath; }
      set
      {
        myVlcLibPath = value;
      }
    }

    public bool Initialise()
    {
      if (!string.IsNullOrEmpty(myVlcLibPath) && Directory.Exists(myVlcLibPath) &&
          File.Exists(Path.Combine(myVlcLibPath, "libvlc.dll")) &&
          File.Exists(Path.Combine(myVlcLibPath, "libvlccore.dll")))
      {
        TryToCreateClient();
        return true;
      }
      else
      {
        return false;
      }

    }

    public bool Initialise(List<String> _options)
    {
      if (!string.IsNullOrEmpty(myVlcLibPath) && Directory.Exists(myVlcLibPath) &&
          File.Exists(Path.Combine(myVlcLibPath, "libvlc.dll")) &&
          File.Exists(Path.Combine(myVlcLibPath, "libvlccore.dll")))
      {
        _options.Insert(0, this.VlcLibPath);
        _options.Add("--plugin-path=" + Path.Combine(this.VlcLibPath, "plugins"));
        this.options = _options.ToArray();
        TryToCreateClient();
        return true;
      }
      else
      {
        return false;
      }
    }

    /// <summary>
    /// Get/Set volume
    /// </summary>
    [DefaultValue(100)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public int Volume
    {
      get { return myVolume; }
      set
      {
        Throw.IfNull(value);
        if (value < 0 || value > 200)
          Throw.Exception("Value must be between 0 and 200.");
        myVolume = value;
        if (myPlayer != null)
          myPlayer.Audio.Volume = value;
        OnPropertyChanged("Volume");
      }
    }

    /// <summary>
    /// Mute volume
    /// </summary>
    [DefaultValue(false)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public bool Mute
    {
      get { return myMute; }
      set
      {
        myMute = value;
        if (myPlayer != null)
          myPlayer.Audio.Mute = value;
        OnPropertyChanged("Mute");
      }
    }

    /// <summary>
    /// Position of selected playing media
    /// </summary>
    [DefaultValue(0)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public float Position
    {
      get { return myPosition; }
      set
      {
        Throw.IfNull(value);

        if ((int)(value * 100) == (int)(myPosition * 100))
          return;

        myPosition = value;
        if (myPlayer != null && myPlayer.State == VlcState.Playing)
          myPlayer.Position = value;
        else
          myPosition = 0;
        OnPropertyChanged("Position");
      }
    }

    /// <summary>
    /// Get/Set fullscreen
    /// </summary>
    [DefaultValue(false)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public bool FullScreen
    {
      get
      {
        if (myPlayer != null)
        {
          if (myPlayer.State == VlcState.Playing || myPlayer.State == VlcState.Paused)
          {
            return myPlayer.Video.FullScreen;
          }
        }
        return false;
      }
      set
      {
        if (myPlayer == null || myPlayer.State != VlcState.Playing)
          return;
        myPlayer.Video.FullScreen = value;
        OnPropertyChanged("FullScreen");
      }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

    private void OnPropertyChanged(string propertyName)
    {
      if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
  }
}